package com.ruicar.afs.cloud.afscase.dispatch.service.impl;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import com.ruicar.afs.cloud.afscase.risk.entity.CaseTortoiseApply;
import com.ruicar.afs.cloud.afscase.risk.service.CaseTortoiseApplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.afscase.channel.entity.ChannelAuthorizeRegion;
import com.ruicar.afs.cloud.afscase.channel.entity.ChannelBaseInfo;
import com.ruicar.afs.cloud.afscase.channel.entity.ChannelRiskInfo;
import com.ruicar.afs.cloud.afscase.channel.service.ChannelAuthorizeRegionService;
import com.ruicar.afs.cloud.afscase.channel.service.ChannelBaseInfoService;
import com.ruicar.afs.cloud.afscase.channel.service.ChannelRiskInfoService;
import com.ruicar.afs.cloud.afscase.dispatch.DispatchContext;
import com.ruicar.afs.cloud.afscase.dispatch.annotation.Dispatch;
import com.ruicar.afs.cloud.afscase.dispatch.enums.DispatchTypeEnum;
import com.ruicar.afs.cloud.afscase.dispatch.service.DispatchBaseServcie;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseBaseInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseCarInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseCarStyleDetail;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseChannelInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseBaseInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseCarInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseCarStyleDetailService;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseChannelInfoService;
import com.ruicar.afs.cloud.afscase.paramconfmanagement.entity.CaseConfParam;
import com.ruicar.afs.cloud.afscase.paramconfmanagement.service.CaseConfParamService;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.IsAssignedEnum;
import com.ruicar.afs.cloud.common.rules.RuleHelper;
import com.ruicar.afs.cloud.common.rules.constants.RuleRunEnum;
import com.ruicar.afs.cloud.common.rules.dto.RuleRunResult;
import com.ruicar.afs.cloud.seats.entity.RegularValue;
import com.ruicar.afs.cloud.seats.service.RegularValueService;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @author cheng.bi
 */
@Slf4j
@Service
@Dispatch(name = "分单时间", dependsOn = "dispatchPriorService", group = DispatchTypeEnum.CREDIT)
public class DispatchTimeBeforService extends DispatchBaseServcie {

    @Autowired
    private CaseBaseInfoService caseBaseInfoService;
    @Autowired
    private CaseChannelInfoService infoService;
    @Autowired
    private RegularValueService valueService;
    @Autowired
    private ChannelRiskInfoService channelRiskInfoService;
    @Autowired
    private CaseCarStyleDetailService carStyleDetailInfoService;
    @Autowired
    private CaseCarInfoService caseCarInfoService;
    @Autowired
    private ChannelBaseInfoService channelBaseInfoService;
    @Autowired
    private ChannelAuthorizeRegionService regionService;
    @Autowired
    private CaseConfParamService caseConfParamService;

    @Autowired
    private CaseTortoiseApplyService caseTortoiseApplyService;

    /**
     * 分单前实际处理方法
     *
     * @param context
     */
    public void process(DispatchContext context) {
        List<CaseBaseInfo> passList = new ArrayList<CaseBaseInfo>(); // 收集可以启动的case传递到下个服务进行处理
        // 获取所有的分单时间输出值
        List<RegularValue> valueList = valueService
                .list(Wrappers.<RegularValue>lambdaQuery().eq(RegularValue::getRuleType, "approveSplittingTime"));
        List<String> ruleList = valueList.stream().filter(s -> {
            String[] times = s.getValue().split("-");
            String startTime = times[0]; // 开始时间
            String endTime = times[1]; // 结束时间
            String timeNow = DateUtil.format(DateUtil.date(), "HH:mm");
            if (startTime.compareTo(timeNow) <= 0 && endTime.compareTo(timeNow) >= 0)
                return true;
            return false;
        }).map(s -> {
            return s.getId().toString();
        }).collect(Collectors.toList()); // 满足当前时间的规则

        log.info("符合当前时间的规则编号:{}", ruleList);
        List<CaseBaseInfo> caseList = (List) (Optional.ofNullable(context.get(KEY)).orElse(new ArrayList()));

        caseList = caseList.stream().sorted(Comparator.nullsLast(Comparator.comparing(CaseBaseInfo::getIsStick, Comparator.nullsLast(Comparator.reverseOrder())))
                .thenComparing(CaseBaseInfo::getPriority, Comparator.nullsLast(Comparator.reverseOrder()))
                .thenComparing(CaseBaseInfo::getCreateTime, Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());

        if (caseList != null && !caseList.isEmpty()) {
            log.info("本次进行分单时间规则数据[{}]", caseList.size());
            for (CaseBaseInfo caseBaseInfo : caseList) {
                JSONObject jsonObject = new JSONObject();
                /** 金融产品 */
                jsonObject.put("productId", String.valueOf(caseBaseInfo.getProductId()));
                /** 业务类型 */
                jsonObject.put("businessType", caseBaseInfo.getBusinessType());
                /** 车辆类型 */
                jsonObject.put("carType", caseBaseInfo.getCarType());
                /** 车辆属性 */
                jsonObject.put("carNature", caseBaseInfo.getCarNature());
                /** 运营方式 */
                jsonObject.put("operateWay", caseBaseInfo.getOperateWay());
                /** 挂靠方式 */
                jsonObject.put("affiliatedWay", caseBaseInfo.getAffiliatedWay());
                CaseCarInfo caseCarInfo = caseCarInfoService.getOne(
                        Wrappers.<CaseCarInfo>query().lambda().eq(CaseCarInfo::getApplyNo, caseBaseInfo.getApplyNo()),
                        false);
                if (ObjectUtil.isNotNull(caseCarInfo)) {
                    /** 车辆级别 */
                    jsonObject.put("carBodyClass", caseCarInfo.getCarBodyClass());
                    /** 车型 */
                    jsonObject.put("modelCode", caseCarInfo.getModelCode());
                    /** 购车地省份 */
                    jsonObject.put("purchaseProvince", caseCarInfo.getPurchaseProvince());
                    /** 购车地城市 */
                    jsonObject.put("purchaseCity", caseCarInfo.getPurchaseCity());
                    List<CaseCarStyleDetail> cartyleDetailInfo = carStyleDetailInfoService
                            .list(Wrappers.<CaseCarStyleDetail>query().lambda().eq(CaseCarStyleDetail::getCarId,
                                    caseCarInfo.getId()));
                    if (cartyleDetailInfo != null && !cartyleDetailInfo.isEmpty()) {
                        /** 是否新能源 */
                        String isGreen = cartyleDetailInfo.get(0).getIsGreen();
                        jsonObject.put("isGreen", isGreen);
                    }
                }
                CaseChannelInfo caseChannelInfo = infoService.getOne(Wrappers.<CaseChannelInfo>query().lambda()
                        .eq(CaseChannelInfo::getApplyNo, caseBaseInfo.getApplyNo()));
                if (ObjectUtil.isNotNull(caseChannelInfo)) {
                    /** 经销商名称 */
                    jsonObject.put("dealerName", caseChannelInfo.getDealerName());
                    ChannelBaseInfo channelBaseInfo = channelBaseInfoService.getOne(Wrappers.<ChannelBaseInfo>query()
                            .lambda().eq(ChannelBaseInfo::getChannelCode, caseChannelInfo.getDealerNo()));
                    if (ObjectUtil.isNotNull(channelBaseInfo)) {
                        /** 合作商注册地址 */
                        jsonObject.put("channelAddress", channelBaseInfo.getChannelAddress());
                        /** 经销商省份 */
                        jsonObject.put("channelProvince", channelBaseInfo.getChannelProvince());
                        /** 经销商城市 */
                        jsonObject.put("channelCity", channelBaseInfo.getChannelCity());
                        /** 渠道归属 */
                        jsonObject.put("channelBelong", channelBaseInfo.getChannelBelong());
                        ChannelRiskInfo channelRiskInfo = channelRiskInfoService
                                .getOne(Wrappers.<ChannelRiskInfo>query().lambda()
                                        .eq(StringUtils.isNotBlank(caseChannelInfo.getDealerNo()),
                                                ChannelRiskInfo::getChannelId, channelBaseInfo.getChannelId())
                                        .eq(StringUtils.isNotBlank(channelBaseInfo.getBusinessType()),
                                                ChannelRiskInfo::getBusinessType, caseBaseInfo.getBusinessType()));
                        if (ObjectUtils.isNotEmpty(channelRiskInfo)) {
                            String qualityGrade = channelRiskInfo.getQualityGrade();
                            /** 优质等级 */
                            jsonObject.put("qualityGrade", qualityGrade);
                            /** 合作商评级 */
                            jsonObject.put("channelGrade", channelRiskInfo.getChannelGrade());
                        }
                        List<ChannelAuthorizeRegion> list = regionService.list(Wrappers.<ChannelAuthorizeRegion>query()
                                .lambda().eq(ChannelAuthorizeRegion::getChannelId, channelBaseInfo.getChannelId()));
                        if (list != null && !list.isEmpty()) {
                            String practicesProvince = "";
                            String practicesCity = "";
                            for (ChannelAuthorizeRegion region : list) {
                                if (IsAssignedEnum.YES.getCode().equals(region.getParentId())
                                        && IsAssignedEnum.YES.getCode().equals(region.getIsParent())) {
                                    practicesProvince = practicesProvince + region.getCode() + ",";
                                }
                                if (IsAssignedEnum.NO.getCode().equals(region.getIsParent())) {
                                    practicesCity = practicesCity + region.getCode() + ",";
                                }
                            }
                            /** 展业省份 */
                            jsonObject.put("practicesProvince",
                                    practicesProvince.substring(0, practicesProvince.length() - 1));
                            /** 展业城市 */
                            jsonObject.put("practicesCity", practicesCity.substring(0, practicesCity.length() - 1));
                        }
                    }
                }
                CaseTortoiseApply tortoiseApply = caseTortoiseApplyService.list(
                        Wrappers.<CaseTortoiseApply>lambdaQuery()
                            .eq(CaseTortoiseApply::getApplyNo,caseBaseInfo.getApplyNo())
                            .isNotNull(CaseTortoiseApply::getNoticeDate)
                            .orderByDesc(CaseTortoiseApply::getNoticeDate)
                ).stream().findFirst().orElse(new CaseTortoiseApply());
                /** 决策引擎返回值 */
                jsonObject.put("decisionValue", tortoiseApply.getDecisionResult());
                // 执行分单时间规则
                RuleRunResult result = RuleHelper.runRule(jsonObject, "approveSplittingTime", false,
                        RuleRunEnum.SERIAL);
                Boolean flag = result.getHit();
                log.info("命中结果:{}, 编号：{}", flag, result.getResults());
                if (flag) {
                    if (!result.getResults().stream().anyMatch(s -> ruleList.contains(s.getRuleNo()))) {
                        log.info("申请编号: {}不满足时间规则，跳过", caseBaseInfo.getApplyNo());
                        continue;
                    }
                } else { // 没有命中 说明没有与之匹配的规则 则调用分单时间参数进行判断
                	 CaseConfParam confParam = caseConfParamService
                             .getOne(Wrappers.<CaseConfParam>query().lambda().eq(CaseConfParam::getParamType, "DISPATCH_TIME").eq(CaseConfParam::getParamStatus, "yes"));
                	if(ObjectUtils.isNotEmpty(confParam.getParamValue())) {
                		String [] timeStr = confParam.getParamValue().split("-");
                		String timeNow = DateUtil.format(DateUtil.date(), "HH:mm");
                        if (timeStr[0].compareTo(timeNow) > 0 || timeStr[1].compareTo(timeNow) < 0) {
                        	continue;
                        }
                	}
                }
                // 纳入可执行参数
                log.info("加载可分单的数据，申请编号:[{}],", caseBaseInfo.getApplyNo());
                passList.add(caseBaseInfo);
                context.put(caseBaseInfo.getId(), jsonObject);
            }
            log.info("符合分单的数据总条数为:[{}]", passList.size());
            context.put(KEY, passList);
        }
    }
}
